home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d27 / inter490.arc / INTPRINT.C < prev    next >
C/C++ Source or Header  |  1990-08-04  |  16KB  |  589 lines

  1. /***********************************************************************/
  2. /* Copyright (c) 1989, 1990  Ralf Brown                    */
  3. /* May be freely redistributed provided no fee is charged, this notice */
  4. /* remains intact, and any changes are clearly marked as such           */
  5. /***********************************************************************/
  6. /* Program History:                               */
  7. /*   v1.00  4/23/89  initial public release                   */
  8. /*             with 4/30/89 list                       */
  9. /*   v1.10  5/21/89  added -I and -f                       */
  10. /*   v1.11  1/6/90   fixed #endif's for compilers which don't handle   */
  11. /*             labels                           */
  12. /*   v1.20  6/8/90   added -r                           */
  13. /*   v1.30  7/14/90  added -b, tables now stay aligned on odd indents  */
  14. /***********************************************************************/
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18.  
  19. #define VERSION "1.30"
  20.  
  21. #define MAXLINE 81   /* at most 80 chars per line (plus newline) */
  22. #define MAXPAGE 200  /* at most 200 lines per page */
  23.  
  24. #ifndef FALSE
  25. #define FALSE 0
  26. #endif
  27. #ifndef TRUE
  28. #define TRUE !FALSE
  29. #endif
  30.  
  31. #ifdef __TURBOC__
  32. #  define PROTOTYPES
  33. #  include <stdlib.h>
  34. int _Cdecl isatty(int handle) ;
  35. void _setenvp(void) {} /* don't need the environment, so don't include it */
  36. int isspace(char c) { return (c == ' ' || c == '\t') ; }
  37. #else
  38. /*#define PROTOTYPES  /* uncomment if compiler supports ANSI-style prototypes */
  39. #  include <ctype.h>
  40. char *itoa(num,buf,radix)   /* not everybody has the same itoa() as TurboC */
  41. int num ;                   /* minimal implementation */
  42. char *buf ;
  43. int radix ;
  44. {
  45.    int count = 0 ;
  46.    int i ; 
  47.    char tmp ;
  48.  
  49.    do {
  50.       buf[count++] = '0' + num % radix ;
  51.       num = num / radix ;
  52.    } while (num) ;
  53.    buf[count] = '\0' ;
  54.    if (count > 1)
  55.       for (i = 0 ; i < count / 2 ; i++)
  56.          {
  57.          tmp = buf[i] ;
  58.          buf[i] = buf[count-i-1] ;
  59.          buf[count-i-1] = tmp ;
  60.          }
  61.    return buf ;
  62. }
  63. #endif /* __TURBOC__ */
  64.  
  65. /***********************************************/
  66.  
  67. #ifdef PROTOTYPES
  68. void usage(void) ;
  69. void indent_line(FILE *fp) ;
  70. void put_line(FILE *fp, int len) ;
  71. int divider_line(char *line) ;
  72. void output_line(char *line,FILE *fp) ;
  73. void fill_buffer(int lines, int lines_per_page) ;
  74. int find_page_break(int lines) ;
  75. void summarize(FILE *summary, int line, int pages_printed) ;
  76. void start_format(char *line) ;
  77. void print_line(char *line) ;
  78. void print_buffer(int first, int last, int lines_per_page, int total_lines, int use_FF) ;
  79. void main(int argc, char **argv) ;
  80. #endif /* PROTOTYPES */
  81.  
  82. /***********************************************/
  83.  
  84. char buffer[MAXPAGE][MAXLINE] ;
  85. char num[6] ;
  86. char summary_line[MAXLINE] ;
  87.  
  88. int pages_printed = 0 ;
  89. int indent = 0 ;
  90. int page_numbers = FALSE ;
  91. int do_summary = FALSE ;
  92. int do_formats = FALSE ;
  93. int IBM_chars = FALSE ;
  94. int boldface = FALSE ;
  95. int echo_format = FALSE ;
  96. FILE *summary ;
  97. FILE *formats ;
  98.  
  99. int first_page = 0 ;
  100. int last_page = 9999 ;
  101.  
  102. /***********************************************/
  103.  
  104. void usage()
  105. {
  106.    fputs("INTPRINT v", stderr) ;
  107.    fputs(VERSION, stderr) ;
  108.    fputs(" Copyright (c) 1989,1990 Ralf Brown. Free for non-commercial use.\n\n",stderr) ;
  109.    fputs("Usage: intprint [options] [lines [page_size]] <intlist >output\n",stderr) ;
  110.    fputs("\t'lines' defaults to 60\n",stderr) ;
  111.    fputs("\tif page_size is given, only linefeeds will be used to advance\n",stderr) ;
  112.    fputs("Options:\n",stderr) ;
  113.    fputs("\t-p\tadd page numbers\n",stderr) ;
  114.    fputs("\t-nN\tassume N pages have been printed from previous parts\n",stderr) ;
  115.    fputs("\t-rN:M\tprint only pages N through M\n",stderr) ;
  116.    fputs("\t-b\tboldface title lines and Return:/Note:\n",stderr) ;
  117.    fputs("\t-e\tassume 'elite' mode (96 characters per line)\n",stderr) ;
  118.    fputs("\t-iN\tindent output N spaces\n",stderr) ;
  119.    fputs("\t-E\tspecifies that the printer is an Epson FX80 or compatible\n",stderr) ;
  120.    fputs("\t\t-E forces -e -i8\n",stderr) ;
  121.    fputs("\t-I\tprinter supports IBM graphics characters\n",stderr) ;
  122.    fputs("\t-sfile\twrite a one-line-per-function summary to 'file'\n",stderr) ;
  123.    fputs("\t-ffile\twrite all data structures to 'file'\n",stderr) ;
  124.    exit(1) ;
  125. }
  126.  
  127. /***********************************************/
  128.  
  129. void indent_line(fp)
  130. FILE *fp ;
  131. {
  132.    int ind ;
  133.  
  134.    for (ind = 0 ; ind < indent ; ind++)
  135.       fputc(' ', fp) ;
  136. }
  137.  
  138. /***********************************************/
  139.  
  140. void put_line(fp,len)
  141. FILE *fp ;
  142. int len ;
  143. {
  144.    int i ;
  145.  
  146.    if (IBM_chars)
  147.       for (i = 0 ; i < len ; i++)
  148.          fputc(196,fp) ;  /* single horizontal line */
  149.    else
  150.       for (i = 0 ; i < len ; i++)
  151.          fputc('-',fp) ;
  152. }
  153.  
  154. /***********************************************/
  155.  
  156. int divider_line(line)
  157. char *line ;
  158. {
  159.    return strncmp(line,"--------",8) == 0 ;
  160. }
  161.  
  162. /***********************************************/
  163.  
  164. void output_line(line,fp)
  165. char *line ;
  166. FILE *fp ;
  167. {
  168.    int pos = 0 ;
  169.    char bold[10] ;
  170.  
  171.    if (boldface)
  172.       {
  173.       if (strncmp(line,"INT ",4) == 0)
  174.      {
  175.      indent_line(fp) ;
  176.      fputs(line,fp) ;
  177.      fputc('\r',fp) ;
  178.      }
  179.       else if (strncmp(line,"Return:",7) == 0 || strncmp(line,"Note:",5) == 0 ||
  180.            strncmp(line,"Notes:",6) == 0 || strncmp(line,"BUG:",4) == 0 ||
  181.            strncmp(line,"SeeAlso:",8) == 0)
  182.      {
  183.      strncpy(bold,line,sizeof bold) ;
  184.      *strchr(bold,':') = '\0' ;
  185.          indent_line(fp) ;
  186.      fputs(bold,fp) ;
  187.      fputc('\r',fp) ;
  188.      }
  189.       }
  190.    indent_line(fp) ;
  191.    if (indent % 8)
  192.       {
  193.       while (*line)
  194.      {
  195.      if (*line == '\t')
  196.         do {
  197.            fputc(' ',fp) ;
  198.            } while (++pos % 8) ;
  199.      else
  200.         {
  201.         fputc(*line,fp) ;
  202.         pos++ ;
  203.         }
  204.      line++ ;
  205.      }
  206.       }
  207.    else
  208.       fputs(line,fp) ;
  209.    fputc('\n',fp) ;
  210. }
  211.  
  212. /***********************************************/
  213.  
  214. void fill_buffer(lines,lines_per_page)
  215. int lines, lines_per_page ;
  216. {
  217.    int i, last ;
  218.  
  219.    if (lines)
  220.       for (i = lines ; i < lines_per_page ; i++)
  221.      strcpy(buffer[i-lines], buffer[i]) ;
  222.    else
  223.       lines = lines_per_page ;
  224.    for (i = lines_per_page - lines ; i < lines_per_page ; i++)
  225.       {
  226.       buffer[i][0] = '\0' ;  /* force empty line in case of EOF */
  227.       fgets(buffer[i], sizeof(buffer[i]), stdin) ;
  228.       last = strlen(buffer[i]) - 1 ;
  229.       if (last < 0)
  230.      last = 0 ;
  231.       if (buffer[i][last] == '\n')
  232.      buffer[i][last] = '\0' ;  /* strip the newline */
  233.       }
  234. }
  235.  
  236. /***********************************************/
  237.  
  238. int find_page_break(lines)
  239. int lines ;
  240. {
  241.    int i ;
  242.  
  243.    for (i = 0 ; i < 10 ; i++)
  244.       {
  245.       if (strcmp(buffer[lines-i-1],"\n") == 0 ||
  246.           strlen(buffer[lines-i-1]) == 0 ||
  247.           divider_line(buffer[lines-i-1]))
  248.          return lines - i ;
  249.       }
  250.    return lines ;
  251. }
  252.  
  253. /***********************************************/
  254.  
  255. void summarize(summary, line, pages_printed)
  256. FILE *summary ;
  257. int line, pages_printed ;
  258. {
  259.    char *s ;
  260.    int i ;
  261.    int max_descrip ;
  262.    int len ;
  263.  
  264.    s = buffer[line] ;
  265.    if (strncmp(s, "INT ", 4) == 0)   /* start of an entry? */
  266.       {
  267.       summary_line[3] = summary_line[0] = ' ' ;
  268.       summary_line[1] = s[4] ;   /* output interrupt number */
  269.       summary_line[2] = s[5] ;
  270.       summary_line[4] = '\0' ;
  271.       len = 4 ;
  272.       s = buffer[line+1] ;
  273.       while (*s && isspace(*s))
  274.          s++ ;
  275.       if (strncmp(s,"AX",2) == 0)
  276.          i = 4 ;
  277.       else if (strncmp(s,"AH",2) == 0)
  278.          i = 2 ;
  279.       else
  280.          i = 0 ;
  281.       if (i)
  282.          {
  283.      while (*s && *s != '=')
  284.             s++ ;
  285.          s++ ;  /* skip the equal sign */
  286.          while (*s && isspace(*s))
  287.             s++ ;
  288.          if (strchr("0123456789ABCDEFabcdef",*s) != NULL)
  289.             {
  290.             summary_line[len++] = *s++ ;
  291.             summary_line[len++] = *s++ ;
  292.             summary_line[len++] = ' ' ;
  293.             if (i == 4)
  294.                {
  295.                summary_line[len++] = *s++ ;
  296.                summary_line[len++] = *s ;
  297.                }
  298.             else
  299.                {
  300.                summary_line[len++] = '-' ;
  301.                summary_line[len++] = '-' ;
  302.                }
  303.             summary_line[len++] = ' ' ;
  304.             }
  305.          else
  306.             {
  307.             /* wasn't legal digit, so no numbers */
  308.             strcpy(summary_line+len,"-- -- ") ;
  309.             len += 6 ;
  310.             }
  311.          }
  312.       else
  313.          {
  314.          strcpy(summary_line+len,"-- -- ") ;
  315.          len += 6 ;
  316.          }
  317.       if (page_numbers)
  318.          {
  319.      itoa(pages_printed,num,10) ;
  320.          for (i = strlen(num) ; i < 3 ; i++)
  321.             summary_line[len++] = ' ' ;
  322.          strcpy(summary_line+len,num) ;
  323.          len += strlen(num) ;
  324.          summary_line[len++] = ' ' ;
  325.          }
  326.       s = buffer[line] + 7 ;  /* find function description */
  327.       while (*s && !isspace(*s))
  328.          s++ ;
  329.       while (*s && isspace(*s))
  330.          s++ ;
  331.       max_descrip = (page_numbers ? MAXLINE-16 : MAXLINE-12) ;
  332.       for (i = 0 ; i < max_descrip && *s ; i++)
  333.          summary_line[len++] = *s++ ;
  334.       summary_line[len] = '\0' ;
  335.       if (do_summary)
  336.      output_line(summary_line,summary) ;
  337.       }
  338. }
  339.  
  340. /***********************************************/
  341.  
  342. void start_format(line)
  343. char *line ;
  344. {
  345.    indent_line(formats) ;
  346.    put_line(formats,79) ;
  347.    fputc('\n',formats) ;
  348.    indent_line(formats) ;
  349.    fputs(summary_line,formats) ;
  350.    fputc('\n',formats) ;
  351.    indent_line(formats) ;
  352.    fputc('\t',formats) ;
  353.    fputs(line+10,formats) ;
  354.    fputc('\n',formats) ;
  355.    echo_format = TRUE ;
  356. }
  357.  
  358. /***********************************************/
  359.  
  360. void print_line(line)
  361. char *line ;
  362. {
  363.    if (*line)
  364.       {
  365.       if (divider_line(line))
  366.          {
  367.      indent_line(stdout) ;
  368.          put_line(stdout,79) ;
  369.          fputc('\n', stdout) ;
  370.          echo_format = FALSE ;
  371.          }
  372.       else
  373.          {
  374.      output_line(line, stdout) ;
  375.          if (echo_format)
  376.         output_line(line,formats) ;
  377.          }
  378.       }
  379.    else
  380.       {
  381.       fputc('\n', stdout) ;
  382.       echo_format = FALSE ;
  383.       }
  384. }
  385.  
  386. /***********************************************/
  387.  
  388. void print_buffer(first,last,lines_per_page,total_lines,use_FF)
  389. int first, last, lines_per_page, total_lines ;
  390. int use_FF ;
  391. {
  392.    int i, ind ;
  393.  
  394.    pages_printed++ ;
  395.    for (i = first ; i < last ; i++)
  396.       {
  397.       if (pages_printed >= first_page && pages_printed <= last_page)
  398.      print_line(buffer[i]) ;
  399.       if (do_summary || do_formats)  /* need summary lines if doing formats */
  400.          summarize(summary,i,pages_printed) ;
  401.       if (do_formats && strncmp(buffer[i],"Format of ",10) == 0)
  402.          start_format(buffer[i]) ;
  403.       }
  404.    if (pages_printed >= first_page && pages_printed <= last_page)
  405.       {
  406.       if (page_numbers)
  407.      {
  408.      for (i = last - first ; i < lines_per_page - 1 ; i++)
  409.         fputc('\n', stdout) ;
  410.      indent_line(stdout) ;
  411.      for (ind = 0 ; ind < 38 ; ind++) /* normal indent + 38 spaces */
  412.         fputc(' ', stdout) ;
  413.      fputs("- ", stdout) ;
  414.      itoa(pages_printed, num, 10) ;
  415.      fputs(num, stdout) ;
  416.      fputs(" -\n", stdout) ;
  417.      }
  418.       if (use_FF)
  419.      fputc('\f', stdout) ;
  420.       else
  421.      for (i = page_numbers?lines_per_page:(last-first) ; i<total_lines ; i++)
  422.         fputc('\n', stdout) ;
  423.       }
  424. }
  425.  
  426. /***********************************************/
  427.  
  428. void main(argc,argv)
  429. int argc ;
  430. char *argv[] ;
  431. {
  432.    int lines_per_page = 60 ;
  433.    int total_lines = 66 ;
  434.    int use_FF = TRUE ;
  435.    int Epson_mode = FALSE ;
  436.    int last_line ;
  437.    int body_lines ;
  438.    char *summary_file = NULL ;
  439.    char *formats_file = NULL ;
  440.    char *last_page_num ;
  441.  
  442.    if (argc == 1 && isatty(0))
  443.       usage() ;   /* give help if invoked with no args and keybd input */
  444.    while (argc >= 2 && argv[1][0] == '-')
  445.       {
  446.       switch (argv[1][1])
  447.          {
  448.          case 'e':
  449.             indent = 8 ;
  450.             break ;
  451.          case 'E':
  452.             Epson_mode = TRUE ;
  453.             break ;
  454.          case 'I':
  455.             IBM_chars = TRUE ;
  456.             break ;
  457.          case 'p':
  458.             page_numbers = TRUE ;
  459.             break ;
  460.      case 'b':
  461.         boldface = TRUE ;
  462.         break ;
  463.          case 'n':
  464.         pages_printed = atoi(argv[1]+2) ;
  465.             break ;
  466.      case 'r':
  467.         first_page = atoi(argv[1]+2) ;
  468.         last_page_num = strchr(argv[1]+2, ':') ;
  469.         last_page = last_page_num ? atoi(last_page_num+1) : 0 ;
  470.         if (last_page == 0)
  471.            last_page = 9999 ;
  472.         break ;
  473.          case 'i':
  474.         indent = atoi(argv[1]+2) ;
  475.             break ;
  476.          case 's':
  477.             summary_file = argv[1]+2 ;
  478.             break ;
  479.          case 'f':
  480.             formats_file = argv[1]+2 ;
  481.             break ;
  482.          default:
  483.             usage() ;
  484.          }
  485.       argv++ ;
  486.       argc-- ;
  487.       }
  488.    if (summary_file && *summary_file)
  489.       if ((summary = fopen(summary_file, pages_printed ? "a":"w")) != NULL)
  490.          do_summary = TRUE ;
  491.       else
  492.      fputs("unable to open summary file\n", stderr) ;
  493.    if (formats_file && *formats_file)
  494.       if ((formats = fopen(formats_file, pages_printed ? "a":"w")) != NULL)
  495.          do_formats = TRUE ;
  496.       else
  497.      fputs("unable to open formats file\n", stderr) ;
  498.    if (argc >= 2)
  499.       lines_per_page = atoi(argv[1]) ;
  500.    if (argc == 3)
  501.       {
  502.       total_lines = atoi(argv[2]) ;
  503.       use_FF = FALSE ;
  504.       }
  505.    if (total_lines < lines_per_page)
  506.       {
  507.       total_lines = lines_per_page ;
  508.       use_FF = TRUE ;
  509.       }
  510.    if (argc > 3 || lines_per_page == 0) /* too many or non-numeric first param */
  511.       usage() ;
  512.    if (lines_per_page < 20 || lines_per_page > MAXPAGE)
  513.       {
  514.       fputs("Surely you jest!  At least 20 and at most 200 lines per page.\n\n", stderr) ;
  515.       usage() ;
  516.       }
  517. #ifdef __TURBOC__
  518.    setvbuf(stdin,NULL,_IOFBF,10240) ;  /* use larger disk buffers */
  519.    setvbuf(stdout,NULL,_IOFBF,10240) ; /* for better performance */
  520.    if (do_summary)
  521.       setvbuf(summary,NULL,_IOFBF,4096) ;
  522.    if (do_formats)
  523.       setvbuf(formats,NULL,_IOFBF,4096) ;
  524. #endif /* __TURBOC__ */
  525.    if (do_summary && pages_printed == 0)
  526.       {           /* create header, but only on first part */
  527.       indent_line(summary) ;
  528.       fputs("\t\t\t\tInterrupt Summary\n",summary) ;
  529.       indent_line(summary) ;
  530.       fputs("\t\t\t\t", summary) ;
  531.       put_line(summary,17) ;
  532.       fputs("\n\n",summary) ;
  533.       indent_line(summary) ;
  534.       fputs("INT AH AL", summary) ;
  535.       if (page_numbers)
  536.          fputs(" Page", summary) ;
  537.       fputs("\t\t\tDescription\n", summary) ;
  538.       indent_line(summary) ;
  539.       put_line(summary,79) ;
  540.       fputc('\n', summary) ;
  541.       }
  542.    if (do_formats && pages_printed == 0)
  543.       {           /* create header, but only on first part */
  544.       indent_line(formats) ;
  545.       fputs("\t\t\tData Structure Formats\n", formats) ;
  546.       indent_line(formats) ;
  547.       fputs("\t\t\t", formats) ;
  548.       put_line(formats,22) ;
  549.       fputs("\n\n", formats) ;
  550.       indent_line(formats) ;
  551.       fputs("INT AH AL", formats) ;
  552.       if (page_numbers)
  553.          fputs(" Page", formats) ;
  554.       fputs("\t\tData Structure\n", formats) ;
  555.       }
  556.    if (Epson_mode)
  557.       {
  558.       indent = 0 ;  /* -E overrides -e and -i */
  559.       fputs("\033M\033l\007", stdout) ;
  560.       }
  561.    if (page_numbers)
  562.       body_lines = lines_per_page - 2 ;
  563.    else
  564.       body_lines = lines_per_page ;
  565.    last_line = 0 ;
  566.    while (!feof(stdin))
  567.       {
  568.       fill_buffer(last_line,body_lines) ;
  569.       last_line = find_page_break(body_lines) ;
  570.       print_buffer(0,last_line,lines_per_page,total_lines,use_FF) ;
  571.       }
  572.    if (last_line < body_lines)
  573.       print_buffer(last_line,body_lines,lines_per_page,total_lines,use_FF) ;
  574.    if (Epson_mode)
  575.       {
  576.       fputs("\033M\033l", stdout) ;  /* cancel Elite mode and indent */
  577.       fputc('\0', stdout) ;
  578.       }
  579.    fflush(stdout) ;
  580.    itoa(pages_printed, num, 10) ;
  581.    fputs(num, stderr) ;
  582.    fputs(" pages\n", stderr) ;
  583.    if (do_summary)
  584.       fclose(summary) ;
  585.    if (do_formats)
  586.       fclose(formats) ;
  587.    exit(0) ;
  588. }
  589.